# -*- coding:utf-8 -*-
#! /bin/python

# there is no tkFileDialog in python 3.*
# in python 3.* you should use tkinter instead of Tkinter
import tkinter as tk
from tkinter import ttk
import DuplicateScan
import DuplicatedDirList
from tkinter import filedialog
import os,_thread,threading,shutil
from threading import Timer
import markduplicated
import my_file_op
import my_log
import ProgressStatus

#reload(sys)
#sys.setdefaultencoding("utf-8")

item_prefix = "     "

root = tk.Tk()
root.geometry("680x680")

fr = tk.Frame()
lb_dirs = tk.Listbox(fr, height=7, width=70, selectmode=tk.BROWSE)
scrl1 = tk.Scrollbar(fr)

scrl = tk.Scrollbar(root)
lb_duplicate_files = tk.Listbox(root, height=40, width=73, selectmode=tk.MULTIPLE)
progressbar_var=tk.IntVar()
progressbar = ttk.Progressbar(root, orient="horizontal", mode="determinate", value=100.0, variable=progressbar_var)
show_same_files_or_same_dirs = "same_dirs"
same_files={}
same_dirs={}

def insert_item(event):

    lb_duplicate_files.delete(0,tk.END)
    
    global same_files
    global same_dirs
    global show_same_files_or_same_dirs

    if show_same_files_or_same_dirs == "same_files":
        same_data = same_files
    else:
        same_data = same_dirs

    #sort by size
    keys_list_with_size = []
    for _md5 in same_data.keys():
        if show_same_files_or_same_dirs == "same_files":
            _size = os.path.getsize(same_data[_md5][0])
        else:
            _size = my_file_op.getdirsize(same_data[_md5][0])
        keys_list_with_size.append((_md5,_size))
    keys_list_with_size.sort(key=lambda x:x[1],reverse = True)
    
    #insert to UI
    for i in keys_list_with_size:
        _md5 = i[0]
        _size = i[1]
        lb_duplicate_files.insert(tk.END,my_file_op.human_readablity_size(_size) + " / " + _md5 )
        for item in same_data[_md5]:
            lb_duplicate_files.insert(tk.END,item_prefix+item)


def click_item(event):
    #print lb_duplicate_files.curselection()
    print ("%s"%(lb_duplicate_files.get(tk.ACTIVE)))

lb_duplicate_files.bind('<ButtonRelease-1>', click_item)
lb_duplicate_files.bind('<<InsertItem>>', insert_item)
lb_duplicate_files.configure(yscrollcommand = scrl.set)
scrl['command'] = lb_duplicate_files.yview

scan_instance = DuplicateScan.DuplicateScan()


def ui_refresh():
    global progressbar_var
    p = ProgressStatus.get_rate()
    progressbar_var.set(p)
    #print progressbar_var.get()
    if ProgressStatus.is_running():
        threading.Timer(1, ui_refresh).start()
    else:
        bn_scan["text"] = "scan"

def scan_thread(no,dirs):
    #start scan
    global same_files
    global same_dirs
    same_files = scan_instance.scan_by_md5(dirs)
    #same_files = scan_instance.scan_by_filesize(dirs)

    same_dirs = DuplicatedDirList.compute_same_dir(same_files)

    lb_duplicate_files.event_generate("<<InsertItem>>", when="tail")

    ProgressStatus.stop()
    _thread.exit_thread()


def scan_dir():
    if ProgressStatus.is_running():
        ProgressStatus.stop()
        return
    #tkMessageBox.showinfo( "Hello Python", "Hello World")
    bn_scan["text"] = "stop"
    ProgressStatus.set_workload(1)
    ProgressStatus.start()
    dirs = []
    for i in range(0,lb_dirs.size()):
        dirs.append(lb_dirs.get(i))
    _thread.start_new_thread(scan_thread, (1,dirs))
    #start refresh timter
    threading.Timer(1, ui_refresh).start()


def show_same_dirs_or_files():
    global show_same_files_or_same_dirs
    if bn_show_same_dirs_or_files["text"] == "showing dirs":
        show_same_files_or_same_dirs ="same_files"
        bn_show_same_dirs_or_files["text"] = "showing files"
    else:
        show_same_files_or_same_dirs ="same_dirs"
        bn_show_same_dirs_or_files["text"] = "showing dirs"
    lb_duplicate_files.event_generate("<<InsertItem>>",when="tail")

def click_item_for_del_dir(event):
    if len(lb_dirs.curselection()) == 0:
        return
    lb_dirs.delete(lb_dirs.curselection())

lb_dirs.bind('<ButtonRelease-1>', click_item_for_del_dir)
scrl1['command'] = lb_dirs.yview

def add_dir():
    dir = tk.filedialog.askdirectory()
    if dir == None or dir == "":
        return
    all_paths = lb_dirs.get(0,lb_dirs.size())
    if my_file_op.is_sub_or_parent_dir(all_paths, dir) == False:
        lb_dirs.insert(tk.END,dir)
    else:
        my_log.debug("sub or paranet dir is illegal: " + dir)

def simple_mark_func():
    markduplicated.MarkDuplicatedButFirst(lb_duplicate_files)

def delete_selected_func():
    for i in lb_duplicate_files.curselection():
        _path = lb_duplicate_files.get(i)
        _path = _path[len(item_prefix):]
        #print i,_path.encode("utf8")
        print("%d,%s"%(i, _path))
        try:
            if show_same_files_or_same_dirs == "same_files":
                os.remove(_path)
            else:
                shutil.rmtree(_path)
        except WindowsError:
            #print "error",_path.encode("utf8")
            print("error %s"%( _path))

bn_add_dir = tk.Button(fr,text="Add DIR",command=add_dir)
bn_scan = tk.Button(fr,text="scan",command=scan_dir)
bn_show_same_dirs_or_files = tk.Button(fr,text="showing dirs",command=show_same_dirs_or_files)
bn_simple_mark = tk.Button(fr,text="mark",command=simple_mark_func)
bn_delete_select = tk.Button(fr,text="del selected",command=delete_selected_func)

lb_dirs.grid(row=0,column = 0,rowspan=5,sticky=tk.W+tk.E)
scrl1.grid(row=0,column = 1,rowspan=5,sticky=tk.W+tk.E+tk.N+tk.S)
bn_add_dir.grid(row=0,column = 2,sticky=tk.W+tk.E,padx=0)
bn_scan.grid(row=1,column = 2,sticky=tk.W+tk.E,padx=0)
bn_show_same_dirs_or_files.grid(row=2,column = 2,sticky=tk.W+tk.E,padx=0)
bn_simple_mark.grid(row=3,column = 2,sticky=tk.W+tk.E,padx=0)
bn_delete_select.grid(row=4,column = 2,sticky=tk.W+tk.E,padx=0)

fr.pack(side=tk.TOP,fill=tk.X,expand=tk.TRUE)
progressbar.pack(side=tk.TOP,fill=tk.X)
lb_duplicate_files.pack(side=tk.LEFT,fill=tk.BOTH,expand=tk.TRUE)
scrl.pack(side=tk.RIGHT,fill=tk.Y)

root.mainloop()
